#include "aio_helper.h"
#include "../global/head.h"
#include "../xos/head.h"
#include "../buf/head.h"
#include "aio_callback_thread.h"
#include "aio_impl.h"
#include "aio_tcp.h"
#include "aio_udp.h"
#include "aio_data.h"
#include "aio_key.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos
{
    aio_helper::aio_helper( aio_impl * pAioImpl ) : m_pAioImpl( pAioImpl )
    {
    }

    aio_helper::~aio_helper()
    {
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // true : quit; false : not quit iocp.
    // 
    bool aio_helper::proc( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        using namespace std;
        int nRet = 0;

        // 
        // iocp closed.
        // 
        if( !lpData )
        {
            cout << "iocp closed" << endl;
            return true;
        }

        i_aio::enumAioType eType = lpData->m_eAioType;

        switch( eType )
        {
            // 
            // tcp
            // 
        case i_aio::AIO_TCP_INIT_SERVER_RET:
        case i_aio::AIO_TCP_INIT_SERVER:
        case i_aio::AIO_TCP_CONNECT_RET:
        case i_aio::AIO_TCP_CONNECT:
        case i_aio::AIO_TCP_ACCPET_RET:
        case i_aio::AIO_TCP_ACCPET:
        case i_aio::AIO_TCP_RECV_RET:
        case i_aio::AIO_TCP_RECV:
        case i_aio::AIO_TCP_SEND_RET:
        case i_aio::AIO_TCP_SEND:
        case i_aio::AIO_TCP_CLOSE_HANDLE_RET:
        case i_aio::AIO_TCP_CLOSE_HANDLE:
            {
                nRet = on_tcp( nResult, dwBytes, lpKey, lpData );
                lpData = 0;
            }
            break;

            // 
            // udp
            // 
        case i_aio::AIO_UDP_INIT_RET:
        case i_aio::AIO_UDP_INIT:
        case i_aio::AIO_UDP_RECV_RET:
        case i_aio::AIO_UDP_RECV:
        case i_aio::AIO_UDP_SEND_RET:
        case i_aio::AIO_UDP_SEND:
        case i_aio::AIO_UDP_CLOSE_HANDLE_RET:
        case i_aio::AIO_UDP_CLOSE_HANDLE:
            {
                nRet = on_udp( nResult, dwBytes, lpKey, lpData );
                lpData = 0;
            }
            break;

            // 
            // 
            // 
        default:
            {
            }
            break;
        }

        if( lpData )
        {
            lpData->release();
            lpData = 0;
        }

        return false;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // true : quit; false : not quit iocp.
    // 
    bool aio_helper::on_tcp( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        using namespace std;
        int nRet = 0;

        // 
        // helper object.
        // 
        i_aio::enumAioType eType = lpData->m_eAioType;
        aio_tcp tcp( m_pAioImpl );

        switch( eType )
        {
        case i_aio::AIO_TCP_INIT_SERVER_RET:
            {
                nRet = tcp.tcp_init_server_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_INIT_SERVER:
            {
                nRet = tcp.tcp_init_server( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_CONNECT_RET:
            {
                nRet = tcp.tcp_connect_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_CONNECT:
            {
                nRet = tcp.tcp_connect( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_ACCPET_RET:
            {
                nRet = tcp.tcp_accept_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_ACCPET:
            {
                nRet = tcp.tcp_accept( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_RECV_RET:
            {
                nRet = tcp.tcp_recv_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_RECV:
            {
                nRet = tcp.tcp_recv( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_SEND_RET:
            {
                nRet = tcp.tcp_send_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_SEND:
            {
                nRet = tcp.tcp_send( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_CLOSE_HANDLE_RET:
            {
                nRet = tcp.close_handle_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_TCP_CLOSE_HANDLE:
            {
                nRet = tcp.close_handle( nResult, dwBytes, lpKey, lpData );
            }
            break;
        }

        if( lpData )
        {
            lpData->release();
            lpData = 0;
        }

        return false;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // true : quit; false : not quit iocp.
    // 
    bool aio_helper::on_udp( int nResult, DWORD dwBytes, aio_key * lpKey, aio_data * lpData )
    {
        using namespace std;
        int nRet = 0;

        // 
        // helper object.
        // 
        i_aio::enumAioType eType = lpData->m_eAioType;
        aio_udp udp( m_pAioImpl );

        switch( eType )
        {
        case i_aio::AIO_UDP_INIT_RET:
            {
                nRet = udp.udp_init_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_INIT:
            {
                nRet = udp.udp_init( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_RECV_RET:
            {
                nRet = udp.udp_recv_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_RECV:
            {
                nRet = udp.udp_recv( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_SEND_RET:
            {
                nRet = udp.udp_send_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_SEND:
            {
                nRet = udp.udp_send( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_CLOSE_HANDLE_RET:
            {
                nRet = udp.close_handle_ret( nResult, dwBytes, lpKey, lpData );
            }
            break;
        case i_aio::AIO_UDP_CLOSE_HANDLE:
            {
                nRet = udp.close_handle( nResult, dwBytes, lpKey, lpData );
            }
            break;
        }

        if( lpData )
        {
            lpData->release();
            lpData = 0;
        }

        return false;
    }

} // xos
